"use strict";

const NUMS = [1, 2, 3, 4, 5, 6, 7, 8, 9];

(function(fn) {
    if (fn.fill) {
        return;
    }

    fn.fill = function(v, start, end) {
        end = end && Math.min(end, this.length) || this.length;
        for (var i = start || 0; i < end; i++) {
            this[i] = v;
        }
    };
})(Array.prototype);

function getBlock(matrix, startRowIndex, startColIndex) {
    return NUMS.map(function(n, i) {
        return matrix[startRowIndex + ~~(i / 3)][startColIndex + i % 3];
    });
}

var toolkit = {
    NUMS: NUMS,
    makeMatrix(v) {
        if (typeof v === "undefined") {
            v = 0;
        }

        return NUMS.map(function() {
            var data = new Array(9);
            data.fill(v);
            return data;
        });
    },
    print(matrix, mapper) {
        matrix.forEach(function(row) {
            if (mapper) {
                console.log(row.map(mapper).join(" "));
            } else {
                console.log(row.join(" "));
            }
        });
        return this;
    },
    convertFromBlockCell(blockIndex, cellIndex) {
        return {
            rowIndex: ~~(blockIndex / 3) * 3 + ~~(cellIndex / 3),
            colIndex: (blockIndex % 3) * 3 + ~~(cellIndex % 3)
        };
    },
    getBlock(matrix, index) {
        var startRowIndex = ~~(index / 3) * 3;
        var startColIndex = index % 3 * 3;
        return getBlock(matrix, startRowIndex, startColIndex);
    },
    getBlockByCoor(matrix, rowIndex, colIndex) {
        var startRowIndex = ~~(rowIndex / 3) * 3;
        var startColIndex = ~~(colIndex / 3) * 3;
        return getBlock(matrix, startRowIndex, startColIndex);
    }
};

module.exports = toolkit;
